package com.hh.demo.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.hh.demo.constants.CommonConstants;
import com.hh.demo.constants.DemoError;
import com.hh.demo.domain.*;
import com.hh.demo.dto.RedisTelCodeDto;
import com.hh.demo.dto.RegisterDto;
import com.hh.demo.feignClient.LoginFeignClient;
import com.hh.demo.mapper.UserMapper;
import com.hh.demo.result.JSONResult;
import com.hh.demo.service.IUserAccountService;
import com.hh.demo.service.IUserBaseInfoService;
import com.hh.demo.service.IUserInvitationService;
import com.hh.demo.service.IUserService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.hh.demo.util.AssertUtil;
import com.hh.demo.util.StrUtils;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * <p>
 * 会员登录账号 服务实现类
 * </p>
 *
 * @author goeun
 * @since 2022-07-15
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Resource
    private LoginFeignClient loginFeignClient;
    @Resource
    private RedisTemplate<Object,Object> redisTemplate;
    @Resource
    private IUserBaseInfoService userBaseInfoService;
    @Resource
    private IUserAccountService userAccountService;
    @Resource
    private IUserInvitationService userInvitationService;

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public void register(RegisterDto registerDto) {
        String key = String.format(CommonConstants.REGISTER_TEL_PREFIX, registerDto.getMobile());
        Object o = redisTemplate.opsForValue().get(key);
        AssertUtil.isNotNull(o, DemoError.COMMON_TEL_CODE_NULL.getMessage());

        RedisTelCodeDto redisTelCodeDto = (RedisTelCodeDto) o;
        AssertUtil.isEquals(redisTelCodeDto.getCode(),registerDto.getSmsCode(),DemoError.COMMON_TEL_CODE_ERROR.getMessage());

        JSONResult jsonResult = saveLogin(registerDto);
        AssertUtil.isTrue(jsonResult.isSuccess(),jsonResult.getMessage());
        AssertUtil.isNotNull(jsonResult.getData(),DemoError.LOGIN_SAVE_FAIL.getMessage());
        long loginId = Long.parseLong(jsonResult.getData().toString());
        //保存user
        User user = saveUser(loginId, registerDto.getMobile());
        AssertUtil.isNotNull(user.getId(),DemoError.USER_SAVE_FAIL.getMessage());
        //保存userBseInfo
        initUserInfo(user.getId(),registerDto.getRegChannel(),registerDto.getInvitation());
        //保存userAccount
        initUserAccount(user.getId());
        //保存UserInvitation
        initUserInvitation(user.getId());
    }

    private void initUserInvitation(Long userId) {
        UserInvitation userInvitation = new UserInvitation();
        String newInvitation = StrUtils.getRandomString(4);
        userInvitation.setInvitation(newInvitation);
        userInvitation.setUserId(userId);
        userInvitationService.insert(userInvitation);
    }

    private void initUserAccount(Long userId) {
        UserAccount account = new UserAccount();
        account.setId(userId);
        account.setCreateTime(System.currentTimeMillis());
        userAccountService.insert(account);
    }
    private void initUserInfo(Long userId,Integer regChannel,String invitation) {
        UserBaseInfo info = new UserBaseInfo();
        info.setId(userId);
        info.setCreateTime(System.currentTimeMillis());
        info.setRegChannel(regChannel);
        if (invitation!=null&&!"".equals(invitation.trim())) {
            UserInvitation userInvitation = userInvitationService.selectOne(new EntityWrapper<UserInvitation>().eq("invitation", invitation));
            info.setReferId(userInvitation.getUserId());
        }
        userBaseInfoService.insert(info);
    }
    private User saveUser(Long loginId,String mobile) {
        User user = new User();
        user.setLoginId(loginId);
        user.setPhone(mobile);
        user.setNickName(mobile);
        user.setCreateTime(System.currentTimeMillis());
        insert(user);
        return user;
    }
    private JSONResult saveLogin(RegisterDto dto) {
        Login login = new Login();
        login.setUsername(dto.getMobile());
        login.setPassword(dto.getPassword());
        login.setType(Login.TYPE_USER);
        return loginFeignClient.saveLogin(login);
    }
}
